package com.ray.service;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.auth.NTCredentials;
import org.apache.xmlbeans.impl.xb.xsdschema.NarrowMaxMin;
import org.junit.validator.PublicClassValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.druid.sql.visitor.functions.If;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
import com.google.appengine.api.search.query.QueryParser.andOp_return;
import com.google.appengine.api.search.query.QueryParser.restriction_return;
import com.google.apphosting.api.proto2api.ApiBasePb.DoubleProtoOrBuilder;
import com.google.apphosting.utils.remoteapi.RemoteApiPb.Request;
import com.ray.bean.CompanyMaterialTableBean;
import com.ray.bean.DatatablesViewPageBean;
import com.ray.bean.FeedOrderDetailBean;
import com.ray.bean.FeedingAndReportBean;
import com.ray.bean.HalfMaterialBean;
import com.ray.bean.MaterialTreeBean;
import com.ray.bean.OrderBean;
import com.ray.bean.OrderInfoDetailBean;
import com.ray.bean.PermissionBean;
import com.ray.bean.ProcessBean;
import com.ray.bean.PutOutOrderBean;
import com.ray.bean.PutOutUpdateUnitPriceBean;
import com.ray.bean.PutOutWarehouseBean;
import com.ray.bean.PutoutFowCycleBean;
import com.ray.bean.PutoutSupplierBean;
import com.ray.bean.ReportBean;
import com.ray.bean.WarehouseInOutDetailBean;
import com.ray.bean.WarehouseInSumMoneyBean;
import com.ray.bean.WorkshopProductionCycleBean;
import com.ray.exception.ServiceException;
import com.ray.mapper.PutOutMapperNew;
import com.ray.pojo.MyUser;
import com.ray.util.CreateIdUtil;
import com.ray.util.ExcelExportUtil;
import com.ray.util.RedirectUrlUtil;
import com.ray.util.RequestUtil;
import com.ray.util.ResponseUtil;
import com.ray.util.ReturnStringUtil;
import com.ray.util.StringUtil;
import com.ray.util.TimeAndUnix;

import net.sf.json.JSONArray;

@Service
public class PutOutServiceNew {
	@Autowired
	PutOutMapperNew putOutMapperNew;
	@Autowired
	WorkshopService workshopService;
	@Autowired
	BasicDataService basicDataService;
	@Autowired
	CompanyMaterialService companyMaterialService;
	@Autowired
	OrderService orderService;
	@Autowired
	StructureTreeService structureTreeService;
	@Autowired
	WarehouseService warehouseService;
	
	
	
	/**
	 * 插入外协仓库记录
	 * @param putOutList(外协仓库集合)
	 */
	public void insertAllPutOutWarehouse(List<PutOutWarehouseBean> putOutList) {
		Set<String> orderIdSet=putOutList.stream().map(PutOutWarehouseBean::getOrderId).collect(Collectors.toSet());
		for(String str:orderIdSet) {
			orderService.checkOrderIsFinish(str);
		}
		int row=putOutMapperNew.insertAllPutOutWarehouse(putOutList);
		Assert.isTrue(row>0,ReturnStringUtil.ADD_ERROR);
	}

	
	/**
	 * 生成外协仓库记录
	 * @return
	 */
	public  String insertOnePutOutWarehouse(PutOutWarehouseBean putOutWarehouseBean) {
		Assert.isTrue(putOutWarehouseBean.getSum()>0,"合格数加不合格数必须大于0");
		FeedingAndReportBean feedingAndReportBean=workshopService.GetOrderSystemCount(putOutWarehouseBean.getOrderId(), putOutWarehouseBean.getMaterialType(), putOutWarehouseBean.getRowIndex(),putOutWarehouseBean.getMaterialCode());
		Map map=new HashMap();
		map.put("orderId", putOutWarehouseBean.getOrderId());
		map.put("materialType", putOutWarehouseBean.getMaterialType());
		map.put("rowIndex", putOutWarehouseBean.getRowIndex());
		map.put("loginCompany", putOutWarehouseBean.getCompany());
		List<OrderInfoDetailBean> detailList=this.getOrderInfoDetail(map);
		Assert.isTrue(detailList != null && detailList.size() >0,"订单明细不存在");	
		feedingAndReportBean.setFeddingCount(Long.parseLong(detailList.get(0).getOrderTotal()));
		Assert.isTrue(putOutWarehouseBean.getCount()+putOutWarehouseBean.getNoCount()<=(feedingAndReportBean.getFeddingCount()-feedingAndReportBean.getWorkShopCount()-feedingAndReportBean.getFinishCount()-feedingAndReportBean.getPutOutCount()),
				putOutWarehouseBean.getMaterialType()+"已有:车间:"+feedingAndReportBean.getWorkShopCount()+"、外协:"+feedingAndReportBean.getPutOutCount()+"、成品:"+feedingAndReportBean.getFinishCount()+",最多还可交接至外协"+(feedingAndReportBean.getFeddingCount()-feedingAndReportBean.getWorkShopCount()-feedingAndReportBean.getFinishCount()-feedingAndReportBean.getPutOutCount())+"付");
		List<PutOutWarehouseBean> putOutList=new ArrayList<PutOutWarehouseBean>();
		putOutList.add(putOutWarehouseBean);
		this.insertAllPutOutWarehouse(putOutList);
	    return ReturnStringUtil.ADD_SUCCESS;	
	}
	
	
	
	
    /**
     * 修改交接到外协仓库的数量
     * @param putOutWarehouse(外协仓库bean)
     * @param id(id)
     * @param status(状态 0 )
     * @param count(合格数)
     * @param noCount(不合格数)
     * @param updateUser(修改人)
     */
	public void updatePutoutCount(PutOutWarehouseBean putOutWarehouse) {
		putOutMapperNew.updatePutoutCount(putOutWarehouse);
		
	}

	/**
	 * 审核外协仓库记录
	 * @param id(外协仓库id)
	 * @param map
	 */
	public List<PutOutWarehouseBean> approvalPutOutWarehouseByTypeId(String typeId, Map map) {
		//获取外协记录
		List<PutOutWarehouseBean> putOutWarehouseBeanList=putOutMapperNew.getPutOutWarehouseByTypeId(typeId,null);
		Assert.isTrue(putOutWarehouseBeanList!=null && putOutWarehouseBeanList.size()>0,"外协交接记录不存在");
		Assert.isTrue(putOutWarehouseBeanList.get(0).getStatus()==0,"外协交接记录已审核");
		orderService.checkOrderIsFinish(putOutWarehouseBeanList.get(0).getOrderId());
		Map putOutOrderMap=new HashMap(map);
		putOutOrderMap.put("typeId", typeId);
		int row=putOutMapperNew.approvalPutOutWarehouseByTypeId(putOutOrderMap);
		Assert.isTrue(row>0,"审核失败，请重试");
		return putOutWarehouseBeanList;
	}

	/**
	 * 删除记录
	 * @param id(外协记录id)
	 * @param map
	 * @return
	 */
	public String deletePutOutWarehouse(Map map) {
		Assert.isTrue(map.get("id")!= null && !"".equals(map.get("id").toString()),"未获取到外协id");
		String idString=map.get("id").toString();
	    List<PutOutWarehouseBean> putOutWarehouseBeanList=putOutMapperNew.getPutOutWarehouseByTypeId(idString,null);
		Assert.isTrue(putOutWarehouseBeanList != null && putOutWarehouseBeanList.size()>0,"改记录不存在");
		Assert.isTrue(putOutWarehouseBeanList.get(0).getStatus()==2,"该记录不是退回状态，不可删除");
		List<String> idList=new ArrayList<String>();
		idList.add(idString);
		this.deletePutOutWarehouseByTypeIdList(idList);
		this.deletePutOutOrderByTypeId(idString);
		return ReturnStringUtil.DELETE_SUCCESS;
		
	}
	
	
	/**
	 * 通过外协id删除外协单记录记录
	 * @param idString
	 */
	private String deletePutOutOrderByTypeId(String idString) {
		int row=putOutMapperNew.deletePutOutOrderByTypeId(idString);
		Assert.isTrue(row>0,ReturnStringUtil.DELETE_ERROR);
		return ReturnStringUtil.DELETE_SUCCESS;
	}




	/**
	 * 删除记录
	 * @param otherIdList(外协交接记录id集合)
	 */
	public String  deletePutOutWarehouseByTypeIdList(List<String> otherIdList) {
		Assert.isTrue(otherIdList!=null && otherIdList.size()>0,"未获取到外协交接id");
	    int row=putOutMapperNew.deletePutOutWarehouseByTypeIdList(otherIdList);
	    Assert.isTrue(row>0,ReturnStringUtil.DELETE_ERROR);
	    return ReturnStringUtil.DELETE_SUCCESS;
	}  


	/**
	 * 获取有交接到外协的订单信息
	 * @param map
	 * @param loginCompany(登录人的公司)
	 * @return
	 */
   public List<OrderBean> getPutOutWarehouseOrderList(Map map){
	   return putOutMapperNew.getPutOutWarehouseOrderList(map);
   }
   
   /**
    * 获取交接到外协的订单的物料
    * @param orderId(订单编号)
    * @param map
    * @return
    */
   public List<String> getPutOutOrderMaterialTypeList(Map map){
	   return putOutMapperNew.getPutOutOrderMaterialTypeList(map);
   }
   
   
   /**
    * 获取交接到外协的订单的物料
    * @param id(外协仓库明细id)
    * @param status(状态  1 审核 2退回)
    * @param map
    * @return
    */
   public String approvalPutOutWarehouse(Map map){
	   checkPutOutApprovalPermission(map);
	   Assert.isTrue(map.get("id")!=null && !"".equals(map.get("id").toString()),"未获取到id");
	   Assert.notNull(map.get("status"),"未获取到状态");
	   List<PutOutWarehouseBean> putOutWarehouseBeanList=this.approvalPutOutWarehouseByTypeId(map.get("id").toString(), map);
	   //如果外协仓库是接受方，要同步来源审核
	   if(putOutWarehouseBeanList.get(0).getInOutType()==1) {
		   //如果是车间的话
		   if(putOutWarehouseBeanList.get(0).getSource()==1) {
			   SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
			   map.put("time", simpleDateFormat.format(new Date()));
			   map.remove("id");
			   map.put("id", putOutWarehouseBeanList.get(0).getTypeId());
			   map.put("approvalReason", "外协仓库审核");
			   workshopService.approvalReportByOtherId(map);
		   }
		   //如果是仓库
           if(putOutWarehouseBeanList.get(0).getSource()==2) {
			   Assert.isTrue(1==2,"仓库交接暂不提供审核功能");
		   }
	   }
	   int status=Integer.parseInt(map.get("status").toString());
	   return status==1?ReturnStringUtil.APPROVAL_SUCCESS:ReturnStringUtil.RETURN_SUCCESS;
   }
   
   /**
    * 获取交接到外协的订单的物料
    * @param orderId(订单编号  非必填)
    * @param materialType(物料类型  非必填)
    * @param status(状态 非必填)
    * @param start(开始 非必填)
    * @param length(条数 非必填)
    * @param map
    * @return
    */
   public DatatablesViewPageBean<PutOutWarehouseBean> getPutWarehouseDetail(Map map){
	   DatatablesViewPageBean<PutOutWarehouseBean> datatablesViewPageBean=new DatatablesViewPageBean<PutOutWarehouseBean>();
	   map.put("isApprpval", 2);
	   //外协审核人
	   List<String> putApprovalName=null;
	   
	   int count=putOutMapperNew.getPutWarehouseDetailCount(map);
	   List<String> typeIdList=putOutMapperNew.getWarehouseGroupTypeId(map);
	   map.put("typeIdList", typeIdList);
	   List<PutOutWarehouseBean> list=putOutMapperNew.getPutWarehouseDetail(map);
	   for(PutOutWarehouseBean pp:list) {
		   //如果状态是未审核
		   if(pp.getStatus()==0) {
			   //如果是交接到车间，由车间的人审核
			   if(pp.getSource()==1 && pp.getInOutType()==2) {
				   List<ReportBean> reportBeans=workshopService.getReportByTypeId(pp.getTypeId());
				   if(reportBeans != null && reportBeans.size()>0 ) {
					   map.put("processId", reportBeans.get(0).getProcedur());
					   map.put("workShopId", reportBeans.get(0).getWorkShopName());
					   pp.setApprovalNameList(workshopService.getCanApprovalReportUser(map));
				   }
			   }else {
				   if(putApprovalName==null) {
					   putApprovalName= workshopService.getPutOutApprovalUserName(map);
				   }
				   pp.setApprovalNameList(putApprovalName);
			   }
		   }
	   }
	   datatablesViewPageBean.setReturnData(list);
	   datatablesViewPageBean.setiTotalDisplayRecords(count);
	   datatablesViewPageBean.setiTotalRecords(count);
	   return datatablesViewPageBean;
   }

   
   
   /**
	 * 生成外协单
	 * @param orderId(订单编号)
	 * @param supplierId(外发供应商id)
	 * @param supplierName(外发供应商名称)
	 * @param technology(外发工艺)
	 * @param flowCycle(流程周期)
	 * @param maching(加工对象)
	 * @param color(颜色)
	 * @param count(数量)
	 * @param remark(备注)
	 * @param rowIndex(行号)
	 * @param unitPrice(行号)
	 * @param type(0单物料报工   1整架  2所有)
	 * @param valuationUint(计价单位)
	 * @param valuationCount(计价数量)
	 * additionalMaterialType 附加物料类型
	 * additionalRowIndex 附加行号
	 * @param putoutOrderArray(批量)
	 * @throws CloneNotSupportedException 
	 * @throws ServiceException
	 */
	public String  addPutoutOrder(Map map) throws CloneNotSupportedException {
		Assert.notNull(map.get("putoutOrderArray"),"未获取到外协单信息");
		String putoutOrderArray=map.get("putoutOrderArray").toString();
		JSONArray jsonArray = JSONArray.fromObject(putoutOrderArray);//把String转换为 数组 
		List<PutOutOrderBean> listPutOutOrder= (List<PutOutOrderBean>)JSONArray.toCollection(jsonArray, PutOutOrderBean.class);
        Set<String> orderIdSet=listPutOutOrder.stream().map(PutOutOrderBean::getOrderId).collect(Collectors.toSet());
		orderService.checkOrderIsFinish(listPutOutOrder.get(0).getOrderId());
		List<PutOutWarehouseBean> putOutWarehouseList=new ArrayList<PutOutWarehouseBean>();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		String dateStr=sdf.format(new Date());
		map.put("orderId", listPutOutOrder.get(0).getOrderId());
		List<PutOutOrderBean> orderAleradyPutOutData=putOutMapperNew.getPutoutOrderData(map);
		List<PutOutWarehouseBean> orderPutOutInOutRecordList=putOutMapperNew.getPutWarehouseDetail(map);
		orderPutOutInOutRecordList=orderPutOutInOutRecordList.stream().filter(inout->inout.getStatus()!=2).collect(Collectors.toList());
		Map<String, String> rowIndexIdMap=new HashMap<String,String>();
		for(PutOutOrderBean putOut:listPutOutOrder) {
			Assert.notNull(putOut.getOrderId(),"未获取到订单编号");
			Assert.notNull(putOut.getSupplierId(),"未获取到供应商编号");
			Assert.notNull(putOut.getSupplierName(),"未获取到供应商名称");
			Assert.notNull(putOut.getTechnology(),"未获取到工艺");
			Assert.isTrue(putOut.getFlowCycle()>0,"未获取到流程周期");
			Assert.notNull(putOut.getMaching(),"未获取到加工对象");
			Assert.notNull(putOut.getColor(),"未获取到颜色");
			Assert.notNull(putOut.getType(),"未获取到类型");
			Assert.isTrue(putOut.getCount()>0,"未获取到数量");
			//校验附加物料类型
			this.checkAdditionalMaterialType(putOut,orderAleradyPutOutData);
			PutOutWarehouseBean putOutWarehouseBean=new PutOutWarehouseBean();
			putOutWarehouseBean.setMaterialType(putOut.getMaching());
			putOutWarehouseBean.setNoCount(0);
			putOutWarehouseBean.setOrderId(putOut.getOrderId());
			putOutWarehouseBean.setRowIndex(putOut.getRowIndex());
			putOut.setCreatetime(dateStr);
			putOut.setId(CreateIdUtil.getId(map.get("loginCompany").toString()+"外协"));
			putOut.setCompany(map.get("loginCompany").toString());
			putOut.setCreateUser(map.get("loginUserId").toString());
			putOut.setSource(0);
			putOut.setIsFinish(2);
			
			//如果不是单个物料,需要设置单行typeId
			if(putOut.getType()!=0) {
				if("-1".equals(putOut.getRowIndex())) {//如果是通用物料，则得到对应数量的
					//如果本行没有生成过id,需要为本行设置id
					if(!rowIndexIdMap.containsKey(putOut.getTypeId())) {
						rowIndexIdMap.put(putOut.getTypeId(), StringUtil.getUUID());
					}
					putOut.setTypeId(rowIndexIdMap.get(putOut.getTypeId()));
				}else {
					//如果本行没有生成过id,需要为本行设置id
					if(!rowIndexIdMap.containsKey(putOut.getRowIndex())) {
						rowIndexIdMap.put(putOut.getRowIndex(), StringUtil.getUUID());
					}
					putOut.setTypeId(rowIndexIdMap.get(putOut.getRowIndex()));
				}
			}else {//如果是原物料
				putOut.setTypeId(putOut.getId());
			}
			putOutWarehouseBean.setCompany(putOut.getCompany());
			putOutWarehouseBean.setCreateUser(putOut.getCreateUser());
			putOutWarehouseBean.setId(putOut.getId());
			putOutWarehouseBean.setInOutType(2);//入库
			putOutWarehouseBean.setSource(3);//来源于外协
			putOutWarehouseBean.setStatus(0);//未审核
			putOutWarehouseBean.setSourceName("外协-"+putOut.getSupplierName());
			putOutWarehouseBean.setOtherId(putOut.getTypeId());
			putOutWarehouseBean.setType(putOut.getType());
			putOutWarehouseBean.setTypeId(putOut.getTypeId());
			putOutWarehouseBean.setMaterialCode(putOut.getMaterialCode());
			putOutWarehouseBean.setRemark(putOut.getRemark());
			//分颜色之前
			List<PutOutWarehouseBean> beforeList=orderPutOutInOutRecordList.stream().filter(inout->inout.getMaterialType().equals(putOut.getMaching()) && inout.getMaterialCode().equals(putOut.getMaterialCode())  && putOut.getRowIndex().equals(inout.getRowIndex()) && "".equals(inout.getAdditionalMaterialType())).collect(Collectors.toList());
			//可外发库存
			int putOutWarehouseCount=0;
			int  afterColorCount=0;
			int  beforeColorCount=this.getStockCount(beforeList);
			putOutWarehouseCount+=beforeColorCount;
//			=putOutMapperNew.getOrderSurePutOutCount(putOutWarehouseBean);
			//如果此次外协物料有附加物料(电镀色)  可外发的数量为没有发电镀色的+已经电镀色的库存
			if(!"".equals(putOut.getAdditionalMaterialType())) {
				List<PutOutWarehouseBean> afterList=orderPutOutInOutRecordList.stream().filter(inout->inout.getMaterialType().equals(putOut.getMaching()) && inout.getMaterialCode().equals(putOut.getMaterialCode()) && putOut.getRowIndex().equals(inout.getRowIndex()) && putOut.getAdditionalRowIndex().equals(inout.getAdditionalRowIndex()) && putOut.getAdditionalMaterialType().equals(inout.getAdditionalMaterialType())).collect(Collectors.toList());
				afterColorCount=this.getStockCount(afterList);
				putOutWarehouseCount+=afterColorCount;
				Assert.isTrue(putOutWarehouseCount>=putOut.getCount(),putOutWarehouseBean.getMaterialType()+":外协数不能大于外协库存数"+putOutWarehouseCount);
				//如果发电镀之前的数量小于本次外协数量
				if(beforeColorCount<putOut.getCount()) {
					//如果没有电镀的没有库存，本次纯发电镀后库存
					if(beforeColorCount==0) {
						putOutWarehouseBean.setAdditionalMaterialType(putOut.getAdditionalMaterialType());
						putOutWarehouseBean.setAdditionalRowIndex(putOut.getAdditionalRowIndex());
						putOutWarehouseBean.setCount((int) putOut.getCount());
					}else {//否则的话，出库记录要两次，一次无电镀色，一次有电镀色
						putOutWarehouseBean.setCount(beforeColorCount);//无电镀色库存
						PutOutWarehouseBean putOutWarehouseBean2=putOutWarehouseBean.clone();
						putOutWarehouseBean2.setId(putOutWarehouseBean2.getId()+1);
						putOutWarehouseBean2.setAdditionalMaterialType(putOut.getAdditionalMaterialType());
						putOutWarehouseBean2.setAdditionalRowIndex(putOut.getAdditionalRowIndex());
						putOutWarehouseBean2.setCount((int)(putOut.getCount()-beforeColorCount));
						putOutWarehouseList.add(putOutWarehouseBean2);
					}
				}else {
					putOutWarehouseBean.setCount((int) putOut.getCount());
				}
			}else {
				putOutWarehouseBean.setCount((int) putOut.getCount());
				Assert.isTrue(putOutWarehouseCount>=putOut.getCount(),putOutWarehouseBean.getMaterialType()+":外协数不能大于外协库存数"+putOutWarehouseCount);
			}
			putOutWarehouseList.add(putOutWarehouseBean);
		}
		this.insertAllPutOutOrder(listPutOutOrder);
		this.insertAllPutOutWarehouse(putOutWarehouseList);
		
		
		
		/**
		 * 如果是审核过账
		 */
		boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
		if(isAduit) {
			Map<String,Object> aduitMap=warehouseService.setAduitMap(map);
			aduitMap.put("status", "1");
			aduitMap.put("request", map.get("request"));
			Set<String> typeIds=listPutOutOrder.stream().map(PutOutOrderBean::getTypeId).collect(Collectors.toSet());
			for(String typeId:typeIds) {
				aduitMap.put("typeId", typeId);
				this.approvalPutOutOrder(aduitMap);
			}
		}
		return ReturnStringUtil.SAVE_SUCCESS;
	}
	
	/**
	 * 获取可外发库存
	 * @param beforeList
	 * @return
	 */
	private int getStockCount(List<PutOutWarehouseBean> beforeList) {
		int   stock=beforeList.stream().filter(pp->pp.getInOutType()==1 && pp.getStatus()==1).mapToInt(PutOutWarehouseBean::getSum).sum()-
			  beforeList.stream().filter(pp->pp.getInOutType()==2).mapToInt(PutOutWarehouseBean::getSum).sum();
     	return stock;
	}




	/**
	 * 校验附加物料类型
	 * @param putOutWarehouseBean
	 * @param orderAleradyPutOutData
	 */
	private void checkAdditionalMaterialType(PutOutOrderBean putOut,
		List<PutOutOrderBean> orderAleradyPutOutData) {
	    if(null!=putOut.getAdditionalMaterialType() &&  !"".equals(putOut.getAdditionalMaterialType()) && orderAleradyPutOutData!=null) {
	    	//该物料附加物料报工记录
	    	Set<String> additionalMaterialTypeSet=orderAleradyPutOutData.stream().filter(pp->pp.getMaching().equals(putOut.getMaching()) && pp.getMaterialCode().equals(putOut.getMaterialCode())  && pp.getStatus()!=2 && !"".equals(pp.getAdditionalMaterialType())  )
	    			.map(PutOutOrderBean::getAdditionalMaterialType).collect(Collectors.toSet());
	    	if(additionalMaterialTypeSet.size()>0) {
	    		for(String add:additionalMaterialTypeSet) {
	    			Assert.isTrue(add.equals(putOut.getAdditionalMaterialType()),putOut.getMaching()+"已附加"+add+",不可以再附加"+putOut.getAdditionalMaterialType());
	    		}
	    	}
	    	//如果是单物料，查看单报本物料附加过的物料类型（一种物料单报只能附加一种物料类型）
//	    	if(putOut.getType()==0) {
//	    		Set<String> additionalMaterialTypeSet=orderAleradyPutOutData.stream().filter(pp->pp.getMaching().equals(putOut.getMaching()) && pp.getType()==0 && pp.getStatus()!=2 )
//	    	                .map(PutOutOrderBean::getAdditionalMaterialType).collect(Collectors.toSet());
//	    		if(additionalMaterialTypeSet.size()>0) {
//	    			for(String add:additionalMaterialTypeSet) {
//	    				Assert.isTrue(add.equals(putOut.getAdditionalMaterialType()),putOut.getMaching()+"已附加"+add+",不可以再附加"+putOut.getAdditionalMaterialType());
//	    			}
//	    		}
//	    	}else {
//	    		Set<String> additionalMaterialTypeSet=orderAleradyPutOutData.stream().filter(pp->pp.getType()==putOut.getType() && pp.getStatus()!=2 )
//    	                .map(PutOutOrderBean::getAdditionalMaterialType).collect(Collectors.toSet());
//				if(additionalMaterialTypeSet.size()>0) {
//					for(String add:additionalMaterialTypeSet) {
//						Assert.isTrue(add.equals(putOut.getAdditionalMaterialType()),"已附加"+add+",不可以再附加"+putOut.getAdditionalMaterialType());
//					}
//				}
//	    	}
	    }
	}


	/**
	 * 批量插入外协单
	 * @param putOutOrderList
	 */
	public void insertAllPutOutOrder(List<PutOutOrderBean> putOutOrderList) {
		putOutMapperNew.insertAllPutOutOrder(putOutOrderList);
	}

	/**
	 * 查询外协仓库库存
	 * @param orderId(订单编号)
	 * @param rowIndex(行号)
	 * @param materialType(物料类型)
	 * @param materialCode(物料代码)
	 * @param putOut
	 * @return
	 */
	public long getPutOutWarehouseStockCount(PutOutWarehouseBean putOut) {
		return putOutMapperNew.getPutOutWarehouseStockCount(putOut);
	}
	
	
	/**
	 * 获取外发供应商
	 * @param start(分页参数)
	 * @param length(分页参数)
     * @param status(状态)
	 * @throws ServiceException
	 * @author NateLu
	 * @throws ParseException 
	 */
	public DatatablesViewPageBean<PutoutSupplierBean> getPutoutSupplier(Map map) throws ParseException {
		DatatablesViewPageBean<PutoutSupplierBean> dbvpb = new DatatablesViewPageBean<PutoutSupplierBean>();
		int total = putOutMapperNew.getPutoutSupplierCount(map);
		List<PutoutSupplierBean> equipmentList = putOutMapperNew.getPutoutSupplierData(map);
		for(PutoutSupplierBean psb:equipmentList) {
			psb.setCreateTime(TimeAndUnix.timeToHaoMiao(psb.getCreateTime()));
			psb.setUpdateTime(TimeAndUnix.timeToHaoMiao(psb.getUpdateTime()));
		}
		dbvpb.setiTotalRecords(total);
		dbvpb.setiTotalDisplayRecords(total);
		dbvpb.setReturnData(equipmentList);
		return dbvpb;
	}
	
	
	
	/**
	 * 获取外协周期
	 * @param start(分页参数)
	 * @param length(分页参数)
	 * @param status(状态)
	 * @throws ServiceException
	 * @author NateLu
	 * @throws ParseException 
	 */
	public DatatablesViewPageBean<PutoutFowCycleBean> getPutoutFlowCycle(Map map) throws ParseException {
		DatatablesViewPageBean<PutoutFowCycleBean> dbvpb = new DatatablesViewPageBean<PutoutFowCycleBean>();
		int total = putOutMapperNew.getPutoutFlowCycleCount(map);
		List<PutoutFowCycleBean> equipmentList = putOutMapperNew.getPutoutFlowCycleData(map);
		for(PutoutFowCycleBean psb:equipmentList) {
			psb.setCreateTime(TimeAndUnix.timeToHaoMiao(psb.getCreateTime()));
			psb.setUpdateTime(TimeAndUnix.timeToHaoMiao(psb.getUpdateTime()));
		}
		dbvpb.setiTotalRecords(total);
		dbvpb.setiTotalDisplayRecords(total);
		dbvpb.setReturnData(equipmentList);
		return dbvpb;
	}
	
	
	/**
	 * 获取订单明细
	 * @param orderId(订单编号)
	 * @return
	 */
	public List<OrderInfoDetailBean> getOrderInfoDetail(Map map) {
		Assert.notNull(map.get("orderId"),"未获取到订单编号!");
		List<OrderInfoDetailBean> detailList=putOutMapperNew.getOrderInfoDetail(map);
		Assert.isTrue(null!=detailList && detailList.size()>0,"该订单没有原料明细");
		return detailList;
	}

	
	
	/**
	 * 获取外协单数据
	 * @param start(分页参数)
	 * @param length(分页参数)
	 * @param type(类型 1   根据制单时间筛选   2 根据返回时间筛选  默认1)
	 * @param startTime(开始时间)
	 * @param endTime(结束时间)
	 * @param orderId(订单编号，选填)
	 * @param supplierId(外发供应商id，选填)
	 * @param technology(外发工艺，选填)
	 * @param maching(加工对象，选填)
	 * @param mantissa(尾数，选填)
	 * @param delay(拖期，选填)
	 * @throws ParseException 
	 * @throws ServiceException
	 */
	public DatatablesViewPageBean getPutoutOrder(Map map) throws ParseException {
		DatatablesViewPageBean<PutOutOrderBean> dbvpb = new DatatablesViewPageBean<PutOutOrderBean>();
		List<PutOutOrderBean> putOutOrderList = putOutMapperNew.getPutoutOrderData(map);
		if(null!=putOutOrderList && putOutOrderList.size() > 0) {
			Set<String> putOutIdSet=putOutOrderList.stream().map(PutOutOrderBean::getId).collect(Collectors.toSet());
			List<PutOutOrderBean> putOutPrice=putOutMapperNew.checkPutOutPrice(putOutIdSet);
			if(null==putOutPrice) {
				putOutPrice=new ArrayList<PutOutOrderBean>();
			}
			for(PutOutOrderBean psb:putOutOrderList) {
				List<PutOutOrderBean> priceList=putOutPrice.stream().filter(pp->pp.getId().equals(psb.getId())).collect(Collectors.toList());
				if(priceList.size()>0) {
					psb.setIsCanUpdatePrice(false);
					psb.setUnitPrice(priceList.get(0).getUnitPrice());
				}else {
					psb.setIsCanUpdatePrice(true);
				}
//				psb.setCreatetime(TimeAndUnix.timeToHaoMiao(psb.getCreatetime()));
//				psb.setReturenTime(TimeAndUnix.timeToHaoMiao(psb.getReturenTime()));
//				psb.setApprovalTime(TimeAndUnix.timeToHaoMiao(psb.getApprovalTime()));
			}
		}
	
		dbvpb.setiTotalRecords(putOutOrderList.size());
		dbvpb.setiTotalDisplayRecords(putOutOrderList.size());
		dbvpb.setReturnData(putOutOrderList);
		return dbvpb;
	}
	/**
	 * @name 通过typeId 获取外协明细
	 * @param typeId(id)
	 * @return
	 * @throws ParseException
	 */
	public DatatablesViewPageBean getPutOutDetailByTypeId(Map map) throws ParseException {
		map=this.setMapTypeIdList(map);
		return this.getPutoutOrder(map);
	}

	
	
	
	/**
	 * 同上
	 * @name 获取分类型的外协数据
	 * @param map
	 * @return
	 * @throws ParseException
	 */
	public DatatablesViewPageBean getPutoutOrderGroupType(Map map) throws ParseException {
		DatatablesViewPageBean<PutOutOrderBean> dbvpb = new DatatablesViewPageBean<PutOutOrderBean>();
		int total = putOutMapperNew.getPutoutOrderCount(map);
		List<String> typeIdList=putOutMapperNew.getTypeId(map);
		map.put("typeIdList", typeIdList);
		List<String> approvalNameList=null;
		List<PutOutOrderBean> putOutOrderList = putOutMapperNew.getPutoutOrderData(map);
		for(PutOutOrderBean psb:putOutOrderList) {
			if(psb.status==0) {
				if(null==approvalNameList) {
					approvalNameList=workshopService.getPutOutApprovalUserName(map);
				}
				psb.setApprovalNameList(approvalNameList);
			}
		}
		dbvpb.setiTotalRecords(total);
		dbvpb.setiTotalDisplayRecords(total);
		dbvpb.setReturnData(putOutOrderList);
		return dbvpb;
	}
	
	/**
	 * 设置类型id集合
	 * @param map
	 * @return
	 */
	private Map setMapTypeIdList(Map map) {
		Assert.isTrue(map.get("typeId") != null && !"".equals(map.get("typeId")),"未获取到类型id");
		List<String> typeIdList =new ArrayList<>();
		typeIdList.add(map.get("typeId").toString());
		map.put("typeIdList", typeIdList);
		return map;
	}
	
	
	/**
	 * 审核外协单
	 * @author nate
	 * @param typeId(外协单号类型id)
	 * @param status 1 审核通过  2 退回（审核不通过）
	 * @throws ServiceException
	 */
	public String  approvalPutOutOrder(Map map) {
		checkPutOutApprovalPermission(map);
		Assert.notNull(map.get("status"),"未获取到状态");
		map=this.setMapTypeIdList(map);
		
		
		int status=Integer.parseInt(map.get("status").toString());
		SimpleDateFormat sdf =new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		String dateStr=sdf.format(new Date());   
		map.put("time",dateStr);
		map.remove("status");
		
		
		List<PutOutOrderBean> list=putOutMapperNew.getPutoutOrderData(map);
		Assert.isTrue(list!=null && list.size()>0, "未查找到此外协单");
		PutOutOrderBean putOutOrder=list.get(0);
		Assert.isTrue(putOutOrder.getStatus()==0,"该外协单已审核或已退回，不能再次操作");
		orderService.checkOrderIsFinish(putOutOrder.getOrderId());
		map.put("status", status);
		putOutMapperNew.approvalPutOutOrder(map);
		putOutMapperNew.approvalPutOutWarehouseByOtherId(map);
		this.approvalPutOutWarehouseByTypeId(putOutOrder.getTypeId(), map);
		boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
		if(!isAduit) {
			if(status==1) {
				return ReturnStringUtil.APPROVAL_SUCCESS + workshopService.sendApprovalStatusMassage(status, putOutOrder.getCreateUserId(), map.get("loginUserName").toString(), "外协单审批", RedirectUrlUtil.waiXie);
			}else {
				return ReturnStringUtil.RETURN_SUCCESS + workshopService.sendApprovalStatusMassage(status, putOutOrder.getCreateUserId(), map.get("loginUserName").toString(), "外协单审批", RedirectUrlUtil.waiXie);
			}
		}else {
			return "";
		}
	}
	
	/**
	 * 通过关联id审核外协出入库记录
	 * @param map
	 * @return
	 */
	public int approvalPutOutWarehouseByOtherId(Map map) {
		return putOutMapperNew.approvalPutOutWarehouseByOtherId(map);
	}
	
	
	/**
	 * 获取外协单返回
	 * @param start(分页参数)
	 * @param length(分页参数)
	 * @param startTime(开始时间)
	 * @param endTime(结束时间)
	 * @param orderId(订单编号，选填)
	 * @param supplierId(外发供应商id，选填)
	 * @param technology(外发工艺，选填)
	 * @param maching(加工对象，选填)
	 * @throws ServiceException
	 * @throws ParseException 
	 */
	public DatatablesViewPageBean getPutoutOrderReturn(Map map) throws ParseException {
		DatatablesViewPageBean<PutOutOrderBean> dbvpb = new DatatablesViewPageBean<PutOutOrderBean>();
		
		List<String> approvalNameList=null;
		int total = putOutMapperNew.getPutoutOrderReturnCount(map);
		List<String> typeIdList=putOutMapperNew.getReturnTypeId(map);
		map.put("typeIdList", typeIdList);
		List<PutOutOrderBean> putOutOrderList = putOutMapperNew.getPutoutOrderReturnData(map);
		for(PutOutOrderBean psb:putOutOrderList) {
//			psb.setCreatetime(TimeAndUnix.timeToHaoMiao(psb.getCreatetime()));
//			psb.setReturenTime(TimeAndUnix.timeToHaoMiao(psb.getReturenTime()));
//			psb.setApprovalTime(TimeAndUnix.timeToHaoMiao(psb.getApprovalTime()));
			if(psb.getStatus()==0) {
				if(null==approvalNameList) {
					approvalNameList=workshopService.getPutOutApprovalUserName(map);
				}
				psb.setApprovalNameList(approvalNameList);
			}
		}
		dbvpb.setiTotalRecords(total);
		dbvpb.setiTotalDisplayRecords(total);
		dbvpb.setReturnData(putOutOrderList);
		return dbvpb;
	}
	
	/**
	 * 获取外协返回和退回明细
	 * typeId
	 * @param map
	 * @return
	 */
	public List<PutOutOrderBean> getPutOutReturnAndBackDetail(Map map){
		StringUtil.checkIsTrue(map, "typeId", "未获取到类型id");
		List<String> typeIdList=putOutMapperNew.getReturnTypeIdByPutOutTypeId(map);
		Assert.isTrue(typeIdList!=null && typeIdList.size()>0,"该外协单没有明细记录");
		map.remove("typeId");
		map.put("typeIdList", typeIdList);
		return putOutMapperNew.getPutoutOrderReturnData(map);
	}
	
	
	/**
	 * typeId(类型id)
	 * backCount(退回数量)
	 * valuationCount (退回计价数量)
	 * remark(备注)
	 * @param map
	 * @return
	 */
	public String backPutOutOrder(Map map) {
		checkPutOutApprovalPermission(map);
		StringUtil.checkIsTrue(map, "typeId", "未获取到类型id");
		StringUtil.checkIsTrue(map, "backCount", "未获取到退回数量");
		StringUtil.checkNotNull(map, "remark", "未获取到备注");
		StringUtil.checkNotNull(map, "valuationCount", "未获取到计价数量");
		List<String> typeIdList=new ArrayList<>();
		typeIdList.add(map.get("typeId").toString());
		map.put("typeIdList", typeIdList);
		//退回数量
		Integer backCount=Integer.parseInt(map.get("backCount").toString());
		Double backValuationCount =Double.parseDouble(map.get("valuationCount").toString());
		//typeId对应的外协记录
		List<PutOutOrderBean> list=putOutMapperNew.getPutoutOrderData(map);
		Assert.isTrue(list != null && list.size() >0,"外协记录不存在");
		PutOutOrderBean pob =list.get(0);
		//获取外协可返回数量
		PutOutOrderBean backMap= putOutMapperNew.getBackCountByPutOutId(pob.getId());
		long stockCount=backMap.getCount();
		Double sumValuationCount=backMap.getValuationCount()==null?0:backMap.getValuationCount();
		Assert.isTrue(stockCount > 0,"没有可退回数");
		Assert.isTrue(backCount<=stockCount,"退回数不能大于外协返回数");
		Assert.isTrue(backValuationCount<=sumValuationCount,"退回计价数不能大于外协返回计价数");
		//通过外协信息批量获取外协库存
		List<PutOutWarehouseBean> stockList=putOutMapperNew.getOrderMaterialTypeStockCountListByPutOutList(list);
		
		
		//遍历对应的外协记录
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		Map<String, String> rowIndexIdMap=new HashMap<String,String>();
		String dateStr=sdf.format(new Date());
		for(PutOutOrderBean putOutOrderBean :list) {
			this.checkBackCount(putOutOrderBean,stockList,backCount);
			putOutOrderBean.setReturnId(StringUtil.getUUID());
			putOutOrderBean.setReturnCount(backCount);
			putOutOrderBean=this.setReturnTypeId(rowIndexIdMap,putOutOrderBean);
			putOutOrderBean.setReturenTime(dateStr);
			putOutOrderBean.setReturnUser(map.get("loginUserId").toString());
			putOutOrderBean.setStatus(0);
			putOutOrderBean.setInOutType(2);
			putOutOrderBean.setRemark(map.get("remark").toString());
			putOutOrderBean.setValuationCount(backValuationCount);
		}
		int row=putOutMapperNew.returnPutOutOrderAll(list);
		Assert.isTrue(row>0,ReturnStringUtil.SAVE_ERROR);
	    return ReturnStringUtil.SAVE_SUCCESS;
	}
	
    
	/**
	 * 校验外协仓库库存
	 * @param putOutOrderBean
	 * @param stockList
	 * @param backCount
	 */
	private void checkBackCount(PutOutOrderBean putOutOrderBean, List<PutOutWarehouseBean> stockList,
			Integer backCount) {
		for(PutOutWarehouseBean pp:stockList) {
			if(putOutOrderBean.getOrderId().equals(pp.getOrderId()) && putOutOrderBean.getMaching().equals(pp.getMaterialType()) && putOutOrderBean.getRowIndex().equals(pp.getRowIndex())) {
				Assert.isTrue(backCount<=pp.getCount(),pp.getMaterialType()+",退回数不能大于外协库存数:"+pp.getCount());
			}
		}
	}


	/**
	 * 设置返回的typId
	 * @param rowIndexIdMap
	 * @param putOutOrderBean
	 * @return
	 */
	private PutOutOrderBean setReturnTypeId(Map<String, String> rowIndexIdMap, PutOutOrderBean putOutOrderBean) {
		//如果不是单个物料,需要设置单行typeId
		if(putOutOrderBean.getType()!=0) {
			if("-1".equals(putOutOrderBean.getRowIndex())) {//如果是通用物料，则得到对应数量的
				//如果本行没有生成过id,需要为本行设置id
				if(!rowIndexIdMap.containsKey(putOutOrderBean.getTypeId())) {
					rowIndexIdMap.put(putOutOrderBean.getTypeId(), StringUtil.getUUID());
				}
				putOutOrderBean.setTypeId(rowIndexIdMap.get(putOutOrderBean.getTypeId()));
			}else {
				//如果本行没有生成过id,需要为本行设置id
				if(!rowIndexIdMap.containsKey(putOutOrderBean.getRowIndex())) {
					rowIndexIdMap.put(putOutOrderBean.getRowIndex(), StringUtil.getUUID());
				}
				putOutOrderBean.setTypeId(rowIndexIdMap.get(putOutOrderBean.getRowIndex()));
			}
		}else {//如果是原物料
			putOutOrderBean.setTypeId(putOutOrderBean.getReturnId());
		}
		return putOutOrderBean;
	}


	/**
	 * 外协单返回
	 * @param id(外协单号id)
	 * @param returnCount(返回数量)
	 * @param returnPutoutOrderArray(批量)
	 */
	public String  returnPutOutOrder(Map map) {
		Assert.notNull(map.get("returnPutoutOrderArray"),"未获取到外协单信息");
		String putoutOrderArray=map.get("returnPutoutOrderArray").toString();
		JSONArray jsonArray = JSONArray.fromObject(putoutOrderArray);//把String转换为 数组 
		List<PutOutOrderBean> listPutOutOrder= (List<PutOutOrderBean>)JSONArray.toCollection(jsonArray, PutOutOrderBean.class);
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		Map<String, String> rowIndexIdMap=new HashMap<String,String>();
		String dateStr=sdf.format(new Date());
		for(PutOutOrderBean putOutOrderBean:listPutOutOrder) {
			Assert.isTrue(putOutOrderBean.getId()!= null && !"".equals(putOutOrderBean.getId()),"未获取到id");
			Assert.isTrue(putOutOrderBean.getReturnCount()>0,"请输入大于0的数量");
			map.put("id", putOutOrderBean.getId());
			List<PutOutOrderBean> putOutOrderList = putOutMapperNew.getPutoutOrderData(map);
			PutOutOrderBean putOutOrder=putOutOrderList.get(0);//获取到外协单
			orderService.checkOrderIsFinish(putOutOrder.getOrderId());
			PutOutOrderBean returnMap=putOutMapperNew.getReturnCountByPutOutId(putOutOrder.getId());//通过外协单id获取已经返回数量
			double returnCount=returnMap.getCount();
			double returnValuationCount=returnMap.getValuationCount()==null?0:returnMap.getValuationCount();
			Assert.isTrue(putOutOrder.getCount()>=putOutOrderBean.getReturnCount()+returnCount,"数量不能超过外协单的数量，最多还可返回"+(putOutOrder.getCount()-returnCount)+"付");
			Assert.isTrue(putOutOrder.getValuationCount()>=putOutOrderBean.getValuationCount()+returnValuationCount,"计价数量不能超过外协单计价的数量，最多还可返回"+(putOutOrder.getValuationCount()-returnValuationCount)+putOutOrder.getValuationUint());
			putOutOrderBean.setReturnId(StringUtil.getUUID());
			putOutOrderBean=this.setReturnTypeId(rowIndexIdMap,putOutOrderBean);
			putOutOrderBean.setReturenTime(dateStr);
			putOutOrderBean.setReturnUser(map.get("loginUserId").toString());
			putOutOrderBean.setStatus(0);
			putOutOrderBean.setInOutType(1);
		}
		int row=putOutMapperNew.returnPutOutOrderAll(listPutOutOrder);
		Assert.isTrue(row>0,ReturnStringUtil.SAVE_ERROR);
		boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
		if(isAduit) {
			Map<String,Object> aduitMap=warehouseService.setAduitMap(map);
			aduitMap.put("request", map.get("request"));
			aduitMap.put("status", "1");
			Set<String> typeIds=listPutOutOrder.stream().map(PutOutOrderBean::getTypeId).collect(Collectors.toSet());
			for(String typeId:typeIds) {
				aduitMap.put("typeId", typeId);
				this.approvalPutOutOrderReturn(aduitMap);
			}
		} 
	    return ReturnStringUtil.SAVE_SUCCESS;
	}
	
	
	
	
	/**
	 * 审核外协返回
	 * @author nate
	 * @param typeId(返回id)
	 * @param status 1 审核通过  2 退回（审核不通过）
	 */
	public String  approvalPutOutOrderReturn(Map map) {
		checkPutOutApprovalPermission(map);
		Assert.notNull(map.get("status"),"未获取到状态");
		Assert.notNull(map.get("typeId"),"未获取到类型id");
		int status=Integer.parseInt(map.get("status").toString());
		if(status==1) {
			List<PutOutUpdateUnitPriceBean> updatePriceList=new ArrayList<PutOutUpdateUnitPriceBean>();
			map.remove("status");//移除状态，避免查询时根据状态查找
			List<PutOutOrderBean> putOutOrderBeanReturnList=putOutMapperNew.getPutoutOrderReturnData(map);//根据typeId查找返回单数据
			Assert.isTrue(putOutOrderBeanReturnList!= null && putOutOrderBeanReturnList.size()>0,"未获取到返回信息");
			PutOutOrderBean putOutOrderBeanReturn=putOutOrderBeanReturnList.get(0);
			Assert.isTrue(putOutOrderBeanReturn.getStatus()==0,"此返回单已审核或退回，不能再次操作");
			orderService.checkOrderIsFinish(putOutOrderBeanReturn.getOrderId());
			map.put("id", putOutOrderBeanReturn.getPutOutOrderId());//根据外协单id查找外协单数据
			//外协单数据
			List<PutOutOrderBean> putOutOrderBeanList=putOutMapperNew.getPutoutOrderData(map);
			Assert.isTrue(putOutOrderBeanList!= null && putOutOrderBeanList.size()>0,"未获取到外协单信息");
			PutOutOrderBean putOutOrderBean=putOutOrderBeanList.get(0);
			map.put("status", status);// 状态设回
			SimpleDateFormat sdf =new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
			String dateStr=sdf.format(new Date());
			map.put("time",dateStr);
			//外协单的数量
			//如果是外协返回,外协单数量大于等于已返回数+本次返回数
			if(putOutOrderBeanReturn.getInOutType()==1) {
				Assert.isTrue(putOutOrderBean.getCount()>=putOutOrderBean.getReturnCount()+putOutOrderBeanReturn.getCount(),"最多还可确认："+(putOutOrderBean.getCount()-putOutOrderBean.getReturnCount())+"付");
				Assert.isTrue(putOutOrderBean.getValuationCount()>=putOutOrderBean.getReturnValuationCount()+putOutOrderBeanReturn.getValuationCount(),"最多还可确认："+(putOutOrderBean.getValuationCount()-putOutOrderBean.getReturnValuationCount())+putOutOrderBean.getValuationUint());
				putOutOrderBean.setReturnCount(putOutOrderBean.getReturnCount()+putOutOrderBeanReturn.getCount());
				putOutOrderBean.setReturnValuationCount(putOutOrderBean.getReturnValuationCount()+putOutOrderBeanReturn.getValuationCount());
				if(putOutOrderBean.getCount()<=putOutOrderBean.getReturnCount()) {
					putOutOrderBean.setIsFinish(1);
					putOutOrderBean.setReturenTime(dateStr);
					putOutOrderBean.setReturnUser(map.get("loginUserId").toString());
				}else {
					putOutOrderBean.setIsFinish(2);
				}
			}else {//如果是外协退回，剩余返回数 大于等于此次审核数
				Assert.isTrue(putOutOrderBean.getReturnCount()>=putOutOrderBeanReturn.getCount(),"最多还可确认："+(putOutOrderBean.getReturnCount())+"付");
				Assert.isTrue(putOutOrderBean.getReturnValuationCount()>=putOutOrderBeanReturn.getValuationCount(),"最多还可确认："+(putOutOrderBean.getReturnValuationCount())+putOutOrderBean.getValuationUint());
				putOutOrderBean.setReturnCount(putOutOrderBean.getReturnCount()-putOutOrderBeanReturn.getCount());
				putOutOrderBean.setReturnValuationCount(putOutOrderBean.getReturnValuationCount()-putOutOrderBeanReturn.getValuationCount());
				putOutOrderBean.setIsFinish(2);
				putOutOrderBean.setReturenTime("");
				putOutOrderBean.setReturnUser("");
			}
			//如果外协返回价格和外协单价格不一样
	        if(putOutOrderBean.getUnitPrice()!=putOutOrderBeanReturn.getUnitPrice()) {
	        	PutOutUpdateUnitPriceBean uintBean=new PutOutUpdateUnitPriceBean();
	        	uintBean.setPutOutOrderId(putOutOrderBean.getTypeId());//外协单typeId
	        	uintBean.setBeforeUnitPeice(putOutOrderBean.getUnitPrice());//外协单单价（修改之前价格）
	        	uintBean.setPotOutReturnId(putOutOrderBeanReturn.getTypeId());//外协单返回id
	        	uintBean.setAfterUnitPrice(putOutOrderBeanReturn.getUnitPrice());//修改后的价格
	        	uintBean.setCreateTime(putOutOrderBeanReturn.getReturenTime());
	        	uintBean.setCreateUser(putOutOrderBeanReturn.getReturnUser());
	        	uintBean.setApprovalTime(dateStr);
	        	uintBean.setApprovalUser(map.get("loginUserName").toString());
	        	updatePriceList.add(uintBean);
	        	putOutOrderBean.setUnitPrice(putOutOrderBeanReturn.getUnitPrice());
	        }
			putOutMapperNew.updatePutOutOrder(putOutOrderBean);
			
			List<PutOutWarehouseBean> putOutWarehouseList=new ArrayList<PutOutWarehouseBean>();
			for(PutOutOrderBean returnBean:putOutOrderBeanReturnList) {
				PutOutWarehouseBean putOutWarehouseBean=new PutOutWarehouseBean();
				putOutWarehouseBean.setMaterialType(returnBean.getMaching());
				putOutWarehouseBean.setNoCount(0);
				putOutWarehouseBean.setOrderId(returnBean.getOrderId());
				putOutWarehouseBean.setRowIndex(returnBean.getRowIndex());
				putOutWarehouseBean.setCompany(map.get("loginCompany").toString());
				putOutWarehouseBean.setCount((int) returnBean.getCount());
				putOutWarehouseBean.setCreateUser(map.get("loginUserId").toString());
				putOutWarehouseBean.setId(returnBean.getId());
				putOutWarehouseBean.setInOutType(returnBean.getInOutType());//出入库类型
				putOutWarehouseBean.setAdditionalMaterialType(returnBean.getAdditionalMaterialType());
				putOutWarehouseBean.setMaterialCode(returnBean.getMaterialCode());
				putOutWarehouseBean.setAdditionalRowIndex(returnBean.getAdditionalRowIndex());
				putOutWarehouseBean.setSource(4);//来源于报工
				putOutWarehouseBean.setStatus(1);//未审核
				if(returnBean.getInOutType()==1) {
					putOutWarehouseBean.setSourceName("外协-"+returnBean.getSupplierName()+"-返回");
				}else {
					putOutWarehouseBean.setSourceName("外协-"+returnBean.getSupplierName()+"-退回");
				}
				putOutWarehouseBean.setOtherId(returnBean.getId());
				putOutWarehouseBean.setType(returnBean.getType());
				putOutWarehouseBean.setRowIndex(returnBean.getRowIndex());
				putOutWarehouseBean.setTypeId(returnBean.getTypeId());
				putOutWarehouseList.add(putOutWarehouseBean);
			}
			this.insertAllPutOutWarehouse(putOutWarehouseList);
			if(updatePriceList.size()>0) {
				putOutMapperNew.addPutOutUpdatePriceRecord(updatePriceList);
			}
		}
		putOutMapperNew.approvalPutOutOrderReturn(map);
	
		if(status==1) {
			return ReturnStringUtil.APPROVAL_SUCCESS;
		}else {
			return ReturnStringUtil.RETURN_SUCCESS;
		}
	}
	
	
	/**
	 * 删除外协返回单
	 * @param typeId(id)
	 * @throws ServiceException
	 * @throws ParseException 
	 */
	public String  deletePutOutOrderReturn(Map map) {
		Assert.notNull(map.get("typeId"),"未获取到id");
		List<PutOutOrderBean> putOutOrderBeanList=putOutMapperNew.getPutoutOrderReturnData(map);//根据id查找返回单数据
		Assert.isTrue(putOutOrderBeanList!= null && putOutOrderBeanList.size()>0,"未获取到返回信息");
		PutOutOrderBean putOutOrderBeanReturn=putOutOrderBeanList.get(0);
		Assert.isTrue(putOutOrderBeanReturn.getStatus()!=1,"此返回单已审核，不可删除");
		int row=putOutMapperNew.deletePutOutOrderReturn(map);
		Assert.isTrue(row>=0,ReturnStringUtil.DELETE_ERROR);
		return ReturnStringUtil.DELETE_SUCCESS;
	}

	
	/**
	 * 获取不分页的外协数据
	 * @param map
	 * @return
	 */
	public List<PutOutOrderBean> getPutoutOrderNoPage(Map map){
		return putOutMapperNew.getPutoutOrderData(map);
	}
	/**
	 * 获取外协库存
	 * @param map
	 * @return
	 */
	public List<PutOutWarehouseBean> getPutOutWarehouseCountOrder(Map map){
		map.put("queryType", 1);
		return putOutMapperNew.getPutOutWarehouseCountOrder(map);
	}

	/**
	 * 外协仓库交接到车间或者仓库
	 * @param orderId(订单编号)
	 * @param rowIndex(行号)
	 * @param materialType(物料类型)
	 * @param count(合格数)
	 * @param noCount(不合格数)
	 * @param color(颜色)
	 * @param workShopId(车间id)
	 * @param sourceName(车间名称或者仓库名称)
	 * @param source(1车间  2 仓库)
	 * @param jsonArray
	 * @return
	 */
	public String putOutWarehouseToWorkshopOrWarehouse(Map map) {
		Assert.isTrue(map.get("jsonArray") != null && !"".equals(map.get("jsonArray").toString()),"未获取到json参数");
		MyUser myUser= RequestUtil.getLoginUser((HttpServletRequest)map.get("request"));
		List<PutOutWarehouseBean> list=new ArrayList<PutOutWarehouseBean>();
		String jsonStr=map.get("jsonArray").toString();
		JSONArray jsonArray=JSONArray.fromObject(jsonStr);
		list=(List<PutOutWarehouseBean>) JSONArray.toCollection(jsonArray, PutOutWarehouseBean.class);
		Map<String, String> rowIndexIdMap=new HashMap<String,String>();
		orderService.checkOrderIsFinish(list.get(0).getOrderId());
		map.put("orderId", list.get(0).getOrderId());
		List<PutOutWarehouseBean> orderPutOutInOutRecordList=putOutMapperNew.getPutWarehouseDetail(map);
		orderPutOutInOutRecordList=orderPutOutInOutRecordList.stream().filter(inout->inout.getStatus()!=2).collect(Collectors.toList());
		for(PutOutWarehouseBean putOutWarehouseBean:list) {
			Assert.notNull(putOutWarehouseBean.getOrderId(),"未获取到订单编号");
			Assert.notNull(putOutWarehouseBean.getRowIndex(),"未获取到行号");
			Assert.notNull(putOutWarehouseBean.getMaterialType(),"未获取到物料类型");
			Assert.notNull(putOutWarehouseBean.getCount(),"未获取到合格数");
			Assert.notNull(putOutWarehouseBean.getNoCount(),"未获取到不合格数");
			Assert.notNull(putOutWarehouseBean.getWorkShopId(),"未获取到车间id");
			Assert.notNull(putOutWarehouseBean.getSourceName(),"未获取到来源名称");
			Assert.notNull(putOutWarehouseBean.getSource(),"未获取到来源");
			Assert.isTrue(putOutWarehouseBean.getSum()>0,putOutWarehouseBean.getMaterialType()+"请输入大于0的交接数(合格数+不合格数)");
			putOutWarehouseBean.setAdditionalColor(null==putOutWarehouseBean.getAdditionalColor()?"":putOutWarehouseBean.getAdditionalColor());
			putOutWarehouseBean.setAdditionalMaterialType(null==putOutWarehouseBean.getAdditionalMaterialType()?"":putOutWarehouseBean.getAdditionalMaterialType());
			putOutWarehouseBean.setAdditionalRowIndex(null==putOutWarehouseBean.getAdditionalRowIndex()?"":putOutWarehouseBean.getAdditionalRowIndex());
			List<PutOutWarehouseBean> inoutList=orderPutOutInOutRecordList.stream().filter(inout->inout.getMaterialType().equals(putOutWarehouseBean.getMaterialType()) && inout.getRowIndex().equals(putOutWarehouseBean.getRowIndex()) && putOutWarehouseBean.getAdditionalMaterialType().equals(inout.getAdditionalMaterialType()) && inout.getAdditionalRowIndex().equals(putOutWarehouseBean.getAdditionalRowIndex())).collect(Collectors.toList());
			long sock=this.getStockCount(inoutList);
//			long sock=putOutMapperNew.getOrderSurePutOutCount(putOutWarehouseBean);
			Assert.isTrue(putOutWarehouseBean.getCount()+putOutWarehouseBean.getNoCount()<=sock,putOutWarehouseBean.getMaterialType()+"交接数不能大于外协库存"+sock); //校验库存
//			int 
			putOutWarehouseBean.setCompany(map.get("loginCompany").toString());//公司
			putOutWarehouseBean.setCreateUser(map.get("loginUserId").toString());//不合格数
			putOutWarehouseBean.setId(StringUtil.getUUID());//id
			putOutWarehouseBean.setInOutType(2);//类型为出库
			putOutWarehouseBean.setStatus(0);//状态为未审核
			putOutWarehouseBean.setOtherId(putOutWarehouseBean.getId());//关联id和本身id一样
			
			//如果不是单个物料,需要设置单行typeId
			if(putOutWarehouseBean.getType()!=0) {
				if("-1".equals(putOutWarehouseBean.getRowIndex())) {//如果是通用物料，则得到对应数量的
					//如果本行没有生成过id,需要为本行设置id
					if(!rowIndexIdMap.containsKey(putOutWarehouseBean.getTypeId())) {
						rowIndexIdMap.put(putOutWarehouseBean.getTypeId(), StringUtil.getUUID());
					}
					putOutWarehouseBean.setTypeId(rowIndexIdMap.get(putOutWarehouseBean.getTypeId()));
				}else {
					//如果本行没有生成过id,需要为本行设置id
					if(!rowIndexIdMap.containsKey(putOutWarehouseBean.getRowIndex())) {
						rowIndexIdMap.put(putOutWarehouseBean.getRowIndex(), StringUtil.getUUID());
					}
					putOutWarehouseBean.setTypeId(rowIndexIdMap.get(putOutWarehouseBean.getRowIndex()));
				}
			}else {//如果是原物料
				putOutWarehouseBean.setTypeId(putOutWarehouseBean.getId());
			}
			if(putOutWarehouseBean.getSource()==1) {//交接到车间
				this.insertToReport(putOutWarehouseBean,myUser);
			}
			if(putOutWarehouseBean.getSource()==2) {//交接到仓库
				this.insertToWarehouse(putOutWarehouseBean,map);
			}
		}
		this.insertAllPutOutWarehouse(list);
		return ReturnStringUtil.SAVE_SUCCESS;
	}




	/**
	 * 外协交接到仓库
	 * @param putOutWarehouseBean
	 * @param map
	 */
	private void insertToWarehouse(PutOutWarehouseBean putOutWarehouseBean, Map map) {
		Assert.notNull(null,"暂无交接至仓库功能");
	}




	/**
	 * 外协交接到车间
	 * @param putOutWarehouseBean
	 * @param myUser 
	 * @param map 
	 */
	private void insertToReport(PutOutWarehouseBean putOutWarehouseBean, MyUser myUser) {
		OrderBean orderBean=orderService.getOrderByOrderId(putOutWarehouseBean.getOrderId());
		List<ReportBean> list=new ArrayList<ReportBean>();   
		String workShopId=putOutWarehouseBean.getWorkShopId();
		WorkshopProductionCycleBean wpcb=basicDataService.getWCById(workShopId);
	    Assert.notNull(wpcb,"该车间不存在");
	    ProcessBean processBean=basicDataService.getProcessByWorkShopId(wpcb.getId());
	    Assert.notNull(processBean,"该车间还没有交接入库工序");
	    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy/MM/dd");
	    StringBuilder weiXinNeiRong=new StringBuilder("");
	    weiXinNeiRong.append("工序名称:").append(processBean.getProcessName()).append("\n")
	    .append("工厂型号:").append(orderBean.getFactoryId()).append("\n");
		ReportBean reportBean=new ReportBean();
		reportBean.setSortKey(workshopService.getSort());
		reportBean.setCompany(putOutWarehouseBean.getCompany());
		reportBean.setOrderId(putOutWarehouseBean.getOrderId());
		reportBean.setMachining(putOutWarehouseBean.getMaterialType());
		reportBean.setColor(putOutWarehouseBean.getColor());
		reportBean.setWorkShopName(workShopId);
		reportBean.setProcedur(processBean.getId());
		reportBean.setTime(simpleDateFormat.format(new Date()));
		reportBean.setQualified(putOutWarehouseBean.getCount());
		reportBean.setNoQualified(putOutWarehouseBean.getNoCount());
		reportBean.setTouchPeople(putOutWarehouseBean.getCreateUser());
		simpleDateFormat=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		reportBean.setTouchTime(simpleDateFormat.format(new Date()));
		reportBean.setRowIndex(putOutWarehouseBean.getRowIndex());
		reportBean.setStatus(0);
		reportBean.setOtherId(putOutWarehouseBean.getId());
		reportBean.setOtherType(8);
		reportBean.setMachingType(putOutWarehouseBean.getType());
		reportBean.setTypeId(putOutWarehouseBean.getTypeId());
		reportBean.setAdditionalMaterialType(putOutWarehouseBean.getAdditionalMaterialType());
		reportBean.setAdditionalRowIndex(putOutWarehouseBean.getAdditionalRowIndex());
		reportBean.setMaterialCode(putOutWarehouseBean.getMaterialCode());
		weiXinNeiRong.append("物料:").append(reportBean.getMachining()).append("\n")
        .append("颜色:").append(reportBean.getColor()).append("\n")
		 .append("合格数:").append(reportBean.getQualified()).append("\n")
		 .append("不合格数:").append(reportBean.getNoQualifiedReason()==null?0:reportBean.getNoQualifiedReason()).append("\n");
		list.add(reportBean);
		workshopService.insertReport(list);
	    simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		String day=simpleDateFormat.format(new Date());
		//发送报工消息提醒
		String returnErrorStr=workshopService.sendWechatmsg("有新的报工数据，请尽快审核" ,"报工审核",wpcb,myUser,simpleDateFormat.format(new Date()) ,wpcb.getWorkshopName()+"报工："+weiXinNeiRong.toString(),1,RedirectUrlUtil.reportWork+"#userId="+reportBean.getTouchPeople()+"&startTime="+day+"&endTime="+day+"&orderId="+reportBean.getOrderId()+"&procedureId="+reportBean.getProcedur(),processBean); 
	}
	
	
	/**
	 * 删除外协单
	 * @param typeId(类型id)
	 * @throws ServiceException 
	 * @throws ParseException 
	 */
	public String deletePutOutOrder(Map map) {
		map=this.setMapTypeIdList(map);
		List<PutOutOrderBean> list=putOutMapperNew.getPutoutOrderData(map);
		List<String> idList=new ArrayList<String>();
		Assert.isTrue(list!=null && list.size()>0, "未查找到此外协单");
		for(PutOutOrderBean putOut:list) {
			Assert.isTrue(putOut.getStatus()!=1,"此外协单已审核不可删除");
			idList.add(putOut.getTypeId());
		}
		int row=putOutMapperNew.deletePutOutOrderByTypeId(map.get("typeId").toString());
		Assert.isTrue(row>0,"");
		this.deletePutOutWarehouseByTypeIdList(idList);
		return ReturnStringUtil.RETURN_SUCCESS;
	}
	
	/**
	 * 添加外发周期
	 * @param supplierId(供应商Id)
	 * @param technology(加工工艺)
	 * @param flowCycle(整数)
	 * @throws ServiceException
	 * @author NateLu
	 */
	public String addPutoutFlowCycle(Map map) {
		Assert.notNull(map.get("supplierId"), "请选择供应商!");
		Assert.notNull(map.get("technology"), "请输入工艺!");
		Assert.notNull(map.get("flowCycle"), "请输入流程周期!");
		Assert.isTrue(this.checkPutoutFlowCycle(map),"该供应商下已存在该工艺");
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		String dateStr=sdf.format(new Date());
		map.put("createTime", dateStr);
		map.put("id", StringUtil.getUUID());
		int row=putOutMapperNew.addPutoutFlowCycle(map);
		Assert.isTrue(row>0,ReturnStringUtil.ADD_ERROR);
		return ReturnStringUtil.ADD_SUCCESS;
	}
	
	
	/**
	 * 校验供应商下的工艺是否存在
	 * @param supplierId(供应商id)
	 * @param technology(工艺)
	 * @param id(非必传)
	 * @return
	 */
	private boolean checkPutoutFlowCycle(Map map) {
		Assert.notNull(map.get("technology"), "未获取到工艺!");
		Assert.notNull(map.get("supplierId"), "未获取到供应商id!");
		boolean bool=false;
		List<String> strList=putOutMapperNew.checkPutoutFlowCycle(map);
		if(strList==null  || strList.size()<=0) {
			bool=true;
		}
		return bool;
	}
	
	/**
	 * 修改外协周期
	 * @param id(必传)
	 * @param technology(加工工艺，传则改)
	 * @param supplierId(供应商id，传则改)
	 * @param flowCycle(流程周期,传则改)
	 * @param status(状态,传则改)
	 * @param unitPrice(单价,传则改)
	 * @throws ServiceException
	 * @author NateLu
	 */
	public String  updatePutoutFlowCycle(Map map) {
		Assert.notNull(map.get("id"), "未获取到id!");
		Assert.isTrue(this.checkPutoutFlowCycle(map),"该供应商下已存在该工艺");
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		String dateStr=sdf.format(new Date());
		map.put("updateTime", dateStr);
		int row=putOutMapperNew.updatePutoutFlowCycle(map);
		Assert.isTrue(row>0,ReturnStringUtil.UPDATE_ERROR);
		return ReturnStringUtil.UPDATE_SUCCESS;
	}
	
	/**
	 * 添加外发供应商
	 * @param supplierName(供应商名称)
	 * @param contactUser(联系人)
	 * @param contactPhone(联系电话)
	 * @throws ServiceException
	 * @author NateLu
	 */
	public String  addPutoutSupplier(Map map) {
		Assert.notNull(map.get("supplierName"), "请输入供应商名称!");
		Assert.notNull(map.get("contactUser"), "请输入联系人");
		Assert.notNull(map.get("contactPhone"), "请输入联系电话!");
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		String dateStr=sdf.format(new Date());
		map.put("createTime", dateStr);
		map.put("id", StringUtil.getUUID());
		int row=putOutMapperNew.addPutoutSupplier(map);
	    Assert.isTrue(row>=0,ReturnStringUtil.ADD_ERROR);
		return ReturnStringUtil.ADD_SUCCESS;
	}
	
	/**
	 * 修改外发供应商
	 * @param id(必传)
	 * @param supplierName(必传)
	 * @param status(可不传，传则修改)
	 * @param contactUser((可不传，传则修改)
	 * @param contactPhone(可不传，传则修改)
	 * @throws ServiceException
	 * @author NateLu
	 */
	public String updatePutoutSupplier(Map map) {
		Assert.notNull(map.get("id"), "未获取到id!");
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
		String dateStr=sdf.format(new Date());
		map.put("updateTime", dateStr);
	    int row=putOutMapperNew.updatePutoutSupplier(map);
	    Assert.isTrue(row>0,ReturnStringUtil.UPDATE_ERROR);
	    return ReturnStringUtil.UPDATE_SUCCESS;
	}
	
	//加工工艺  部门  单价  计价数量  合计  完成计价数量
    //导出外协数据
	@RequestMapping("/downlodePutOut")
	@ResponseBody
	public void downlodePutOut(Map map) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException {
	   HttpServletRequest request=(HttpServletRequest) map.get("request");
	   HttpServletResponse response=(HttpServletResponse) map.get("response");
	    map.put("start", null);
		map.put("length", null);
		List<PutOutOrderBean> tableList=this.getPutoutOrderNoPage(map);
		tableList=this.groupPutOut(tableList,map);
		for(PutOutOrderBean put:tableList) {
			if(put.getIsFinish()==1||put.getIsFinish()==-1) {
				put.setFinishStr("已完成");
			}else {
				put.setFinishStr("未完成");
			}
			if(put.getStatus()==0) {
				put.setStatusStr("待审核");
			}else if(put.getStatus()==1) {
				put.setStatusStr("已审核");
			}else {
				put.setStatusStr("已退回");
			}
		}
		String [] tableHeadFields={"部门","订单编号","工厂型号","客户型号","客户订单号","供应商","加工工艺","流程周期","加工对象","颜色","外协数量","单价","备注","是否完成","完成时间","完成数量","完成计价数量","制单时间","制单人","状态","审核人","审核时间"};
		String [] fields={"deptName","companyOrderId","factoryId","coustomId","customerOrderId","supplierName","technology","flowCycle","maching","color","count","unitPrice","remark","finishStr","returenTime","returnCount","returnValuationCount","createtime","createUser","statusStr","approvalUser","approvalTime"};
		String tempFolder=request.getServletContext().getRealPath("/")+"tempExcelFolder";
		File excelFile=ExcelExportUtil.createExcelFile(tableList,tempFolder,tableHeadFields,fields);
		ResponseUtil.downloadfile(response, excelFile, "外协.xlsx", true);
	}
	
	
	/**
	 * 导出excle按typeId显示半架
	 * @param tableList
	 * @param map
	 * @return
	 */
	private List<PutOutOrderBean> groupPutOut(List<PutOutOrderBean> tableList, Map map) {
		if(tableList.size() <= 0 ) {
			return tableList;
		}
		List<PutOutOrderBean> returnList=new ArrayList<PutOutOrderBean>();
		List<HalfMaterialBean> halfMaterialList=structureTreeService.getHalfMaterialNameList(map);
	    Map<String,List<PutOutOrderBean>> groupMap=tableList.stream().collect(Collectors.groupingBy(PutOutOrderBean::getTypeId));
		for(String key:groupMap.keySet()) {
			//设置半架
			List<PutOutOrderBean> list=groupMap.get(key);
			PutOutOrderBean putOutOrderBean=list.get(0);
			//设置颜色  色号不为空
			Set<String> colorSet=list.stream().filter(ss->!"".equals(ss.getColor()) && WorkshopService.KUANG_TUI_SET.contains(ss.getMaching())).map(PutOutOrderBean::getColor).collect(Collectors.toSet());
			putOutOrderBean.setColor(colorSet.toString());
			if(0!=putOutOrderBean.getType()) {
				if(-1==putOutOrderBean.getType()) {
					putOutOrderBean.setMaching("整架");
				}else{
					List<String> xx=halfMaterialList.stream().filter(ss->ss.getId().equals(putOutOrderBean.getType()+"")).map(HalfMaterialBean::getHalfMaterialName).collect(Collectors.toList());
				    if(xx.size()>0) {
				    	putOutOrderBean.setMaching(xx.get(0));
				    }
				}
			}
			//如果有电镀
			if(!"".equals(putOutOrderBean.getAdditionalMaterialType())) {
				putOutOrderBean.setMaching(putOutOrderBean.getMaching()+"(电镀)");
			}
			returnList.add(putOutOrderBean);
		}
	    return returnList;
	}


	//导出外协数据
	@RequestMapping("/downlodePutOutReturn")
	@ResponseBody
	public void downlodePutOutReturn(Map map) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException, ParseException {
		HttpServletRequest request=(HttpServletRequest) map.get("request");
		HttpServletResponse response=(HttpServletResponse) map.get("response");
		map.put("start", null);
		map.put("length", null);
		DatatablesViewPageBean<PutOutOrderBean> datatablesViewPageBean=this.getPutoutOrderReturn(map);
		List<PutOutOrderBean> tableList=datatablesViewPageBean.getReturnData();
		tableList=this.groupPutOut(tableList,map);
		for(PutOutOrderBean put:tableList) {
			if(put.getIsFinish()==1||put.getIsFinish()==-1) {
				put.setFinishStr("已完成");
			}else {
				put.setFinishStr("未完成");
			}
			if(put.getStatus()==0) {
				put.setStatusStr("待审核");
			}else if(put.getStatus()==1) {
				put.setStatusStr("已审核");
			}else {
				put.setStatusStr("已退回");
			}
			if(put.getInOutType()==1) {
				put.setReturnTypeStr("外协返回");
			}else {
				put.setReturnTypeStr("外协退回");
			}
		}
		String [] tableHeadFields={"订单编号","工厂型号","客户型号","客户订单号","供应商","加工工艺","流程周期","加工对象","颜色","返回数量","单价","备注","是否完成","返回类型","外协数量(付)","外协计价数量","返回时间","返回制单人","状态","可审核人","返回审核人","返回审核时间"};
		String [] fields={"companyOrderId","factoryId","coustomId","customerOrderId","supplierName","technology","flowCycle","maching","color","returnCount","unitPrice","remark","finishStr","returnTypeStr" ,"count","valuationCount", "returenTime","createUser","statusStr","approvalUser","approvalTime"};
		String tempFolder=request.getServletContext().getRealPath("/")+"tempExcelFolder";
		File excelFile=ExcelExportUtil.createExcelFile(tableList,tempFolder,tableHeadFields,fields);
		ResponseUtil.downloadfile(response, excelFile, "外协返回.xlsx", true);
	}
	
	/** 
	 * 获取外协出入库记录汇总数据
	 * @param orderId(订单编号)
	 * @param materialType(订单编号)
	 * @param start(订单编号)
	 * @param length(订单编号)
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<PutOutWarehouseBean> getPutWarehouseSumData(Map map){
		map.put("queryType", 2);
		int count=putOutMapperNew.getPutOutWarehouseCountOrderCount(map);
		DatatablesViewPageBean datatablesViewPageBean=new DatatablesViewPageBean<>();
		datatablesViewPageBean.setReturnData(putOutMapperNew.getPutOutWarehouseCountOrder(map));
		datatablesViewPageBean.setiTotalDisplayRecords(count);
		datatablesViewPageBean.setiTotalRecords(count);
		return datatablesViewPageBean;
	}
	
	/**
	 * 获取订单交接到外协仓库的类型
	 * orderId 订单编号
	 * @return
	 */
	public List<Map> getOrderInWarehouseType(Map map){
		StringUtil.checkIsTrue(map, "orderId", "未获取到订单编号");
		List<Map> retrunList=new ArrayList<Map>();
		List<MaterialTreeBean> materialTreeBeans=new ArrayList<MaterialTreeBean>();
		List<HalfMaterialBean> halfMaterialList=structureTreeService.getHalfMaterialTypeList(map);
		if(null==halfMaterialList) {
			halfMaterialList=new ArrayList<HalfMaterialBean>();
		}
		Map<String,List<HalfMaterialBean>> halfMap=halfMaterialList.stream().collect(Collectors.groupingBy(HalfMaterialBean::getNameId));
		List<MaterialTreeBean> aleradyPutOutMaterialList=putOutMapperNew.getOrderInWarehouseType(map);
		materialTreeBeans=orderService.setReportMaterial(aleradyPutOutMaterialList, halfMap, materialTreeBeans);
		List<MaterialTreeBean> mm=aleradyPutOutMaterialList.stream().filter(pp->"0".equals(pp.getId())).collect(Collectors.toList());
		materialTreeBeans.addAll(mm);
		for(MaterialTreeBean mmm:materialTreeBeans) {
			Map map2=new HashMap<String,Integer>();
			map2.put("type", Integer.parseInt(mmm.getId()));
			map2.put("materialType", mmm.getMaterialType());
			retrunList.add(map2);
		}
		return retrunList;
	}
	
	
	/**
	 * 修改外协实际价格
	 * typeId (类型id)
	 * actualPrice (实际价格)
	 * @param map
	 * @return
	 */
	public  String updatePutOutActualPrice(Map map) {
		StringUtil.checkIsTrue(map, "typeId", "未获取到类型id");
		StringUtil.checkIsTrue(map, "actualPrice", "未获取到类型实际价格");
		int row=putOutMapperNew.updatePutOutActualPrice(map);
		Assert.isTrue(row>0,ReturnStringUtil.UPDATE_ERROR);
		return ReturnStringUtil.UPDATE_SUCCESS;
	}
	
	
	
	/**
	 * 校验外协审核权限
	 * @param map
	 */
	public Boolean checkPutOutApprovalPermission(Map map) {
		HttpServletRequest request=(HttpServletRequest) map.get("request");
		MyUser myUser=RequestUtil.getLoginUser(request);
		Set<String> urlSet=new HashSet<String>();
		if(null!=myUser.getPermissionList()) {
			urlSet=myUser.getPermissionList().stream().map(PermissionBean::getUrl).collect(Collectors.toSet());
		}
		Assert.isTrue(urlSet.contains("/putOutNew/approvalPutOutWarehouse"),"没有外协审核权限");
		return true;
	}
	
	
	/**
	 * 获取外协单总价
	 * @return
	 */
    public Double getPutOutOrderSumPrice(Map map) {
    	return  putOutMapperNew.getPutOutOrderSumPrice(map);
    }
    
    /**
     * orderId 订单编号
     * 获取订单电镀色
     * @return
     */
    public Map getDianDuColorList(Map map){
    	Map returnMap=new HashMap();
    	List<OrderInfoDetailBean> dianDuColorList= putOutMapperNew.getDianDuColorList(map);
    	returnMap.put("dianDuColorList", dianDuColorList);
    	List<PutOutWarehouseBean> aleradyPutOutMaterialList=putOutMapperNew.getAleradyPutOutMaterialList(map);
    	returnMap.put("aleradyPutOutMaterialList", aleradyPutOutMaterialList);
//    	if(dianDuColorList!=null) {
//    		//存储电镀物料和样式五物料对应关系map
//    		Map<String,Set<String>> mapList=new HashMap<String,Set<String>>();
//    		//已经交接到外协的物料及附加物料信息（仅样式五）
//    		if(null==aleradyPutOutMaterialList) {
//    			aleradyPutOutMaterialList=new ArrayList<PutOutWarehouseBean>();
//    		}
//    		Set<String> materialTypeSet=dianDuColorList.stream().map(OrderInfoDetailBean::getMaterialType).collect(Collectors.toSet());
//    		for(String str:materialTypeSet) {
//    			Set<String> canAddSet=aleradyPutOutMaterialList.stream().filter(pp->"".equals(pp.getAdditionalMaterialType()) || str.equals(pp.getAdditionalMaterialType())).map(PutOutWarehouseBean::getMaterialType).collect(Collectors.toSet());
//    			mapList.put(str, canAddSet);
//    		}
//    	}
    	return returnMap;
    }
    
    /**
     * 获取订单明细电镀信息
     * @return
     */
    public List<OrderInfoDetailBean> getDianDuInfo(Map map){
    	return putOutMapperNew.getDianDuColorList(map);
    }
    
    /**
     * 将外协单设置完成
     * @isUrl true 
     * typeId 类型id
     * @param map
     * @return
     */
    public String setPutOutOrderIsFinish(Map map) {
    	StringUtil.checkIsTrue(map, "typeId", "未获取到类型id");
    	int row=putOutMapperNew.setPutOutOrderIsFinish(map);
    	Assert.isTrue(row>0,ReturnStringUtil.OPERATION_ERROR);
    	return ReturnStringUtil.SET_SUCCESS;
    }
    
   /**************************************外协财务*********************************************/ 
    /**
     * 获取外协财务详情
     * @param request
     * @return
     * @throws ParseException 
     * @throws ServiceException
     */
    public Map<String,Object> getPutOutSumMoneyDetail(Map map) throws ParseException{
    	map.put("isFinish", 1);
    	map.put("type", 1);
		Map<String,Object> data = new HashMap<String,Object>();
		if(map.get("isSum")!=null) {
			data=this.getPutOutSumMoney(map);
			data=data==null?new HashMap():data;
		}
		DatatablesViewPageBean<PutOutOrderBean> datatablesViewPageBean =  this.getPutoutOrderGroupType(map);
		datatablesViewPageBean.setReturnData(this.groupPutOut(datatablesViewPageBean.getReturnData(), map));
		data.put("list",datatablesViewPageBean);
		return data; 
	}


    /**
     * 获取外协财务汇总
     * @param map
     * @return
     */
    private Map<String, Object> getPutOutSumMoney(Map map) {
		return putOutMapperNew.getPutOutSumMoney(map);
	}
    
    
    /**
     * 获取外协财务汇总
     * @param map
     * @return
     */
    public List<Map> getPutOutSum(Map map) {
    	map.put("type", 1);
    	map.put("isFinish", 1);
    	return putOutMapperNew.getPutOutSum(map);
    }


    /**
     * 通过关联id获取外协出入库记录
     * @param id
     * @return
     */
	public List<PutOutWarehouseBean> getPutOutWarehouseByOtherId(String otherId) {
		List<PutOutWarehouseBean> list=putOutMapperNew.getPutOutWarehouseByOtherId(otherId);
		return list;
	}



	/**
	 * 外协财务导出
	 * @throws ParseException 
	 */
	public void exportPutOutSumMoneyDetail(Map paramMap) throws ServiceException, CloneNotSupportedException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException, ParseException{
		HttpServletRequest request=(HttpServletRequest) paramMap.get("request");
		HttpServletResponse response=(HttpServletResponse) paramMap.get("response");
		Map map=RequestUtil.getRequestAllParam(request);
		map.put("start", null);
		map.put("length", null);
		DatatablesViewPageBean<PutOutOrderBean> datatablesViewPageBean =  this.getPutoutOrderGroupType(map);
		List<PutOutOrderBean> tableList=datatablesViewPageBean.getReturnData();
		tableList=this.groupPutOut(tableList,map);
		for(PutOutOrderBean pp :tableList) {
			if(pp.getIsBalance()==1) {
				pp.setBalanceStr("已结算");
			}else {
				pp.setBalanceStr("未结算");
			}
			System.out.println(pp.getCreateUser()+":"+pp.getCreateTime());
		}
		String [] tableHeadFields={"订单编号","工厂型号","客户型号","客户订单号","供应商","加工工艺","流程周期","加工对象","颜色","规格","外协数量","单价","计价数量","外协金额","完成数量","完成计价数量","外协完成金额","完成时间","已付金额","增减金额","是否结算","结算时间","制单人","制单时间","备注"};                                                                     
		String [] fields={"orderId","factoryId","coustomId","coustomOrderId","supplierName","technology","flowCycle","maching","color","model","count","unitPrice","valuationCount","totalPrice","returnCount","returnValuationCount","returnTotalPrice","returenTime","receiptPaymentPrice","addReducePrice","balanceStr","balanceTime","createUser","createTime","remark"};
		String tempFolder=request.getServletContext().getRealPath("/")+"tempExcelFolder";
		File excelFile=ExcelExportUtil.createExcelFile(tableList,tempFolder,tableHeadFields,fields);
		ResponseUtil.downloadfile(response, excelFile, "外协应付.xlsx", true);
	}
	
	/**************************************外协财务*********************************************/ 
}


